//
//
//

#include "darray.h"
#include <stdlib.h>

#include <stdio.h> // for debug

struct DArray
{
    unsigned int used;
    unsigned int total;
    void **data_startor;
};

const int DA_DEFAULT_TOTAL = 100;

//
//
//
darray
da_create()
{
    printf("da_create() start\n");
    // unimplemented

    darray da = (darray)malloc(sizeof(struct DArray));
    da->used = 0;
    da->total = DA_DEFAULT_TOTAL;
    da->data_startor = NULL;

    da->data_startor = malloc(da->total*sizeof(int *));
}


//
//
//
void
da_destroy(darray da)
{
    printf("da_destroy() start\n");
    // unimplemented

    if (da) {
        if (da->data_startor) {
  	    free(da->data_startor);
	}
        free(da);
    }
}

//
//
//
void *
da_add(darray da, int index, void *value)
{
  //    printf("da_add() start\n");
    if (index < 0 || index > da->total - 1) {
        return NULL;
    }
    // @TODO testing to use int * as all pointer type
    ((int **)da->data_startor)[index] = (int *)value;
    da->used++;
    return (void *)value;
}

//
//
//
void *
da_remove(darray da, int index)
{
  //    printf("da_remove() start\n");
    if (index < 0 || index > da->total - 1)
        return NULL;

    int *vp = ((int **)da->data_startor)[index];
    ((int **)da->data_startor)[index] = NULL;
    da->used--;
    //    printf("*vp is %d\n", *vp);
    return (void *)vp;
}

//
//
//
void *
da_get_value(darray da, int index)
{
  //    printf("da_get_value() start\n");
    if (index < 0 || index > da->total - 1)
        return NULL;
    int *vp = ((int **)da->data_startor)[index];
    return (void *)vp;
}

//
//
//
void
da_print(darray da, PrintCB cb)
{
  //    printf("da_print() start\n");
    int i;
    for (i = 0; i < da->total; i++) {
        cb(da_get_value(da, i));
    }    
}

//
// @TODO not a dynamic implement
// need to change the size 1.5 when half
// of space used.
//
void
da_change_size(darray da, int newsize)
{
    printf("da_change_size() start\n\n");
    da->data_startor = realloc(da->data_startor, 200*sizeof(int *));
    da->total = newsize;
}

//
//
//
int
da_foreach(darray da, DoSomeThingCB cb, void *ctx)
{
    printf("da_change_size() start\n");
    int ret = 0;
    int i;

    for (i = 0; i < da->total; i++) {
        int *vp = ((int **)da->data_startor)[i];
	ret = cb((void *)vp, ctx);
	if (ret == 0) {
	    return 0; // error on do someting
	}
    }
}
